#pragma once
#include<iostream>
#include<assert.h>
#include<vector>
#include<time.h>
using std::cout;
using std::endl;

#ifdef _WIN64
    #include<windows.h>
#elif _WIN32
    #include<windows.h>
//#elif  
//Linux
#endif 

static void* SystemAlloc(size_t kpage)
{
    #ifdef  _WIN64
        void* ptr = VirtualAlloc(0, kpage<<13, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    #elif _WIN32
        void* ptr = VirtualAlloc(0, kpage<<13, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    //elif Linux
    #endif

    if(ptr == nullptr)
    throw std::bad_alloc();

    return ptr;
}
template<class T>
class ObjectPool{
public:
    T* New()
    {
        T* obj = nullptr;
        //先看freeList还有没有空间,有直接拿
        //没有获取大块内存
        if(_freeList)
        {
            //freeList头删
            void* next = *(void**)_freeList;
            obj = (T*)_freeList;
            _freeList = next;
        }
        else
        {
            //剩下的内存还够不够一个对象，不够重开
            if(_remainBites < sizeof(T))
            {
                _remainBites = 128*1024;
                // _memory = malloc(128*1024);
                //从堆里申请内存
                _memory = (char*)SystemAlloc(_remainBites >> 13);
                if(_memory == nullptr)
                {
                    throw std::bad_alloc();
                }

            }
            obj = (T*)_memory;
            size_t ObjSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
            _memory += ObjSize;
            _remainBites -= ObjSize;

        }
        //定位new
        new (obj)T;
        return obj;
    }
    void Delete(T* obj)
    {
        obj->~T();
        
        //freeList头插
        *(void**)obj = _freeList;
        _freeList = obj;
    }

private:
    void* _memory = nullptr;//指向大块内存的指针
    size_t _remainBites = 0;//剩余空间的大小 
    void* _freeList = nullptr;//回收的空间

};

// struct TreeNode{
//     typedef TreeNode Node;

//     Node* _left = nullptr;
//     Node* _right = nullptr;
//     int _data;
//     TreeNode()
//     {

//     }
//     TreeNode(const int& data)
//     {
//         _data = data;
//     }
// };

// void text()
// {
// // 申请释放的轮次
// 	const size_t Rounds = 5;

// 	// 每轮申请释放多少次
// 	const size_t N = 1000;

// 	std::vector<TreeNode*> v1;
// 	v1.reserve(N);

// 	size_t begin1 = clock();
// 	for (size_t j = 0; j < Rounds; ++j)
// 	{
// 		for (int i = 0; i < N; ++i)
// 		{
// 			v1.push_back(new TreeNode);
// 		}
// 		for (int i = 0; i < N; ++i)
// 		{
// 			delete v1[i];
// 		}
// 		v1.clear();
// 	}

// 	size_t end1 = clock();

// 	std::vector<TreeNode*> v2;
// 	v2.reserve(N);

// 	ObjectPool<TreeNode> TNPool;
// 	size_t begin2 = clock();
// 	for (size_t j = 0; j < Rounds; ++j)
// 	{
// 		for (int i = 0; i < N; ++i)
// 		{
// 			v2.push_back(TNPool.New());
// 		}
// 		for (int i = 0; i < N; ++i)
// 		{
// 			TNPool.Delete(v2[i]);
// 		}
// 		v2.clear();
// 	}
// 	size_t end2 = clock();

// 	cout << "new cost time:" << end1 - begin1 << endl;
// 	cout << "object pool cost time:" << end2 - begin2 << endl;
// }